HAL SMBUS initialization and configuration functions migration

The goal of this page is to show how to migrate the initialization sequence using STM32CubeMX2:

  • Open STM32CubeMX2 SMBUS configuration panel.

  • Configure the SW layer HAL.

  • Configure the SMBUS main features.

  • Configure the SMBUS advanced features.

  • Configure the SMBUS GPIO pins.

  • Configure the NVIC if the application requires the SMBUS to be used in IT mode.

  • Generate the code.

Note

The configuration below might varies from a series to another.

HAL SMBUS configuration panel

Create a new project with STM32CubeMX2, start by enabling the I2C instance as SMBus, as shown in this example with the selected I2C1, then start the initialization and the main configuration.

Project configuration panel

HAL SMBUS main features configuration

Configure the SMBUS main features.

SMBUS main feature configuration

HAL SMBUS advanced features configuration

Configure the advanced SMBUS features.

SMBUS advanced feature configuration

GPIO configuration

Configure GPIO pins.

SMBUS GPIO configuration

NVIC configuration

Configure the NVIC in case of an interrupt.

SMBUS NVIC configuration

Generated SMBUS initialization and de-initialization sequences

The SMBUS initialization sequence is generated in the mx_i2c1_smbus_init and mx_i2c1_smbus_deinit functions in the mx_i2c1.c file under $YOUR_PROJECT_NAME$/$YOUR_PROJECT_NAME$_SW/generated/STM32Cube_CodeGen.

Related concepts:

STM32CubeMX2 Generated : SMBUS initialization and de-initialization sequences

Topic

Code Snippet HAL1

Code Snippet HAL2

Handle declaration

SMBUS_HandleTypeDef hsmbus;
static hal_smbus_handle_t hsmbus;

Initialization and configuration sequence

static void MX_I2C1_SMBUS_Init(void)
{

  SMBUS_AutonomousModeConfTypeDef sConfigI2C1 = {0};

  hsmbus.Instance = I2C1;
  hsmbus.Init.Timing = 0x80D25052;
  hsmbus.Init.AnalogFilter = SMBUS_ANALOGFILTER_ENABLE;
  hsmbus.Init.OwnAddress1 = 0 << 1U;
  hsmbus.Init.AddressingMode = SMBUS_ADDRESSINGMODE_7BIT;
  hsmbus.Init.DualAddressMode = SMBUS_DUALADDRESS_ENABLE;
  hsmbus.Init.OwnAddress2 = 0xFF;
  hsmbus.Init.OwnAddress2Masks = SMBUS_OA2_NOMASK;
  hsmbus.Init.GeneralCallMode = SMBUS_GENERALCALL_DISABLE;
  hsmbus.Init.NoStretchMode = SMBUS_NOSTRETCH_DISABLE;
  hsmbus.Init.PacketErrorCheckMode = SMBUS_PEC_DISABLE;
  hsmbus.Init.PeripheralMode = SMBUS_PERIPHERAL_MODE_SMBUS_HOST;
  hsmbus.Init.SMBusTimeout = 0x00008493;
  if (HAL_SMBUS_Init(&hsmbus) != HAL_OK)
  {
    Error_Handler();
  }

  /* Configure Autonomous Mode*/
  sConfigI2C1.TriggerState = SMBUS_AUTO_MODE_ENABLE;
  sConfigI2C1.TriggerSelection = SMBUS_GRP1_EXTI5_TRG;
  sConfigI2C1.TriggerPolarity = SMBUS_TRIG_POLARITY_RISING;

  if (HAL_SMBUSEx_SetConfigAutonomousMode(&hsmbus, &sConfigI2C1) != HAL_OK)
  {
    Error_Handler();
  }
}

void HAL_SMBUS_MspInit(SMBUS_HandleTypeDef* hsmbus)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  if(hsmbus->Instance==I2C1)
  {

  /** Initializes the peripherals clock
  */
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_I2C1;
    PeriphClkInit.I2C1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();

    /**I2C1 GPIO Configuration
    PB6     ------> I2C1_SCL
    PB7     ------> I2C1_SDA
    PA1     ------> I2C1_SMBA
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* Peripheral clock enable */
    __HAL_RCC_I2C1_CLK_ENABLE();
    /* I2C1 interrupt Init */
    HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(I2C1_EV_IRQn);
    HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(I2C1_ER_IRQn);
 }

}
hal_smbus_handle_t *mx_i2c1_smbus_init(void)
{
  hal_smbus_config_t smbus_config;

  if (HAL_SMBUS_Init(&hsmbus, HAL_SMBUS1) != HAL_OK)
  {
    return NULL;
  }

  HAL_RCC_I2C1_EnableClock();

  /*
    Timing automatically calculated with:
     - I2C1 input clock at 160000000 Hz
     - I2C clock speed at 100000 Hz
  */
  smbus_config.timing           = 0x80D25052;
  smbus_config.own_address1     = 0 << 1U;
  smbus_config.device_mode      = HAL_SMBUS_PERIPHERAL_MODE_HOST;
  if (HAL_SMBUS_SetConfig(&hsmbus, &smbus_config) != HAL_OK)
  {
    return NULL;
  }

  /* Default value set for digital filter */
  /* HAL_SMBUS_SetDigitalFilter(&hsmbus, 0); */

  HAL_SMBUS_EnableAnalogFilter(&hsmbus);
  HAL_SMBUS_SetConfigOwnAddress2(&hsmbus, 0, HAL_SMBUS_OWN_ADDR2_NOMASK);
  HAL_SMBUS_EnableOwnAddress2(&hsmbus);

  HAL_SMBUS_SLAVE_EnableWakeUp(&hsmbus);

  HAL_SMBUS_SLAVE_EnableAckGeneralCall(&hsmbus);

  HAL_SMBUS_EnableFastModePlus(&hsmbus);

  HAL_SMBUS_EnablePacketErrorCheck(&hsmbus);

  HAL_SMBUS_MASTER_EnableAlertIT(&hsmbus);

  hal_smbus_timeout_config_t timeout_config;

  /* Timeout automatically calculated with:
    Timeout A at 1171 ns
    Timeout A is used to detect SCL_LOW
    Timeout B at 132 ns
  */
  timeout_config.timeout_a = 0x493;
  timeout_config.timeout_a_mode = HAL_SMBUS_TIMEOUTA_MODE_SCL_LOW;
  timeout_config.timeout_b = 0x84;
  /*Set timeout configuration */
  HAL_SMBUS_SetConfigTimeout(&hsmbus2, &timeout_config);

  hal_smbus_am_trig_config_t autonomous_trig_config =
  {
    .source = HAL_SMBUS_AM_TRIG_GRP1_EXTI5,
    .trigger_polarity = HAL_SMBUS_AM_TRIG_RISING
  };

  if (HAL_SMBUS_AM_SetConfigTrigger(&hsmbus, &autonomous_trig_config) != HAL_OK)
  {
    return NULL;
  }

  HAL_SMBUS_AM_EnableTrigger(&hsmbus);

  HAL_RCC_GPIOB_EnableClock();

  HAL_RCC_GPIOA_EnableClock();

  hal_gpio_config_t  gpio_config;

  /**
    I2C1 GPIO Configuration
    PB6   --------->  I2C1_SCL
    PB7   --------->  I2C1_SDA
    **/
  gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
  gpio_config.output_type = HAL_GPIO_OUTPUT_OPENDRAIN;
  gpio_config.pull        = HAL_GPIO_PULL_NO;
  gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
  gpio_config.alternate   = HAL_GPIO_AF_4;
  HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_6 | HAL_GPIO_PIN_7, &gpio_config);


  /**
    I2C1 GPIO Configuration
    PA1   --------->  I2C1_SMBA
    **/
  gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
  gpio_config.output_type = HAL_GPIO_OUTPUT_OPENDRAIN;
  gpio_config.pull        = HAL_GPIO_PULL_NO;
  gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
  gpio_config.alternate   = HAL_GPIO_AF_4;
  HAL_GPIO_Init(HAL_GPIOA, HAL_GPIO_PIN_1, &gpio_config);


  if (HAL_RCC_I2C1_SetKernelClkSource(HAL_RCC_I2C1_CLK_SRC_PCLK1) != HAL_OK)
  {
    return NULL;
  }
  /* Enable the Event interruption for I2C */
  HAL_CORTEX_NVIC_SetPriority(I2C1_EV_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
  HAL_CORTEX_NVIC_EnableIRQ(I2C1_EV_IRQn);

  /* Enable the Error interruption for I2C */
  HAL_CORTEX_NVIC_SetPriority(I2C1_ERR_IRQn, HAL_CORTEX_NVIC_PREEMP_PRIORITY_0, HAL_CORTEX_NVIC_SUB_PRIORITY_0);
  HAL_CORTEX_NVIC_EnableIRQ(I2C1_ERR_IRQn);

  return &hsmbus;
}

Deinitialization sequence

void MX_SMBUS_DeInit(void)
{
  if (HAL_SMBUS_DeInit(&hsmbus) != HAL_OK)
  {
    Error_Handler();
  }
}
void HAL_SMBUS_MspDeInit(SMBUS_HandleTypeDef* hsmbus)
{
  if(hsmbus->Instance==SMBUS1)
  {

    __HAL_RCC_SMBUS1_CLK_DISABLE();
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7);
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1);

    HAL_DMA_DeInit(hsmbus->hdmarx);
    HAL_DMA_DeInit(hsmbus->hdmatx);

    HAL_NVIC_DisableIRQ(SMBUS1_EV_IRQn);
    HAL_NVIC_DisableIRQ(SMBUS1_ER_IRQn);

  }

}
void mx_i2c1_smbus_deinit(void)
{
  /* Disable the Error interruption for I2C */
  HAL_CORTEX_NVIC_DisableIRQ(I2C1_ERR_IRQn);

  (void)HAL_SMBUS_DeInit(&hsmbus);

  HAL_RCC_I2C1_Reset();

  HAL_RCC_I2C1_DisableClock();

  /* Deinitialization of I2C1: I2C1_SCL,I2C1_SDA  */
  HAL_GPIO_DeInit(HAL_GPIOB, HAL_GPIO_PIN_6 | HAL_GPIO_PIN_7);

  /* Deinitialization of I2C1: I2C1_SMBA  */
  HAL_GPIO_DeInit(HAL_GPIOA, HAL_GPIO_PIN_1);

}

IRQ handle function

void I2C1_EV_IRQHandler(void)
{
  HAL_SMBUS_EV_IRQHandler(&hsmbus);
}
void I2C1_ERR_IRQHandler(void)
{
  HAL_SMBUS_ER_IRQHandler(&hsmbus);
}
void I2C1_EV_IRQHandler(void)
{
  HAL_SMBUS_EV_IRQHandler(&hsmbus);
}
void I2C1_ERR_IRQHandler(void)
{
  HAL_SMBUS_ER_IRQHandler(&hsmbus);
}